﻿using System.Web;
using ARS.Control.Common.EntityManage;
using ARS.Control.Custom.Entity.Attributes;
using ARS.Control.Custom.Entity.Fields;
using ARS.Control.Custom.Entity.Model;
using ARS.Control.Factory;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ARS.Control.Custom.Entity.Widget
{
    public abstract class EntityBaseControl:Panel
    {
        #region 变量
        /// <summary>
        /// 控件形态
        /// </summary>
        protected int type;

        private DataBase.Provider.IDbProvider _dbProvider;
        public DataBase.Provider.IDbProvider DbProvider
        {
            get
            {
                if (_dbProvider == null)
                {
                    _dbProvider = DataBase.Provider.DbProvider.GetInstance();
                    
                }
                return _dbProvider;
            }
        }

        /// <summary>
        /// 是否使用缓存
        /// </summary>
        public bool IsEntityUseCache
        {
            get;
            set;
        }

        private EntityToSql _EntityToSql;
        /// <summary>
        /// 实体转换sql
        /// </summary>
        public EntityToSql EntityToSql
        {
            get
            {
                if (_EntityToSql == null)
                {
                    _EntityToSql = new EntityToSql(Entity, EntityTableInfo);
                }
                return _EntityToSql;
            }
        }

        private EntityTableInfo _EntityTableInfo;

        /// <summary>
        /// 实体基本信息
        /// </summary>
        public EntityTableInfo EntityTableInfo
        {
            get
            {
                if (_EntityTableInfo == null)
                {
                    if (IsEntityUseCache)
                    {

                        _EntityTableInfo = this.GetCacheEntityTableInfo();
                    }
                    else
                    {
                        _EntityTableInfo = new EntityTableInfo(Entity, type);
                    }
                }
                return _EntityTableInfo;
            }
        }

        /// <summary>
        /// 获取缓存对象
        /// </summary>
        /// <returns></returns>
        protected abstract EntityTableInfo GetCacheEntityTableInfo();



        /// <summary>
        /// 实体对象
        /// </summary>
        public object Entity
        {
            get;
            set;
        }

        private Type _typeModel;
        protected Type TypeModel
        {
            get
            {
                if (_typeModel == null)
                {
                    //if (Entity == null)
                    //{
                    //    throw new HttpException(404, "Not Found"); 
                    //}
                    _typeModel = Entity.GetType();
                }
                return _typeModel;
            }
        }
        /// <summary>
        /// 是否添加
        /// </summary>
        public bool IsAdd = true;

        /// <summary>
        /// 主键传值
        /// </summary>
        public string RequestKey
        {
            get;
            set;
        }

        /// <summary>
        /// 使用主键的方式
        /// </summary>
        public bool IsUseKey = true;

        /// <summary>
        /// 加密主键
        /// </summary>
        public bool IsEncryptKey
        {
            get;
            set;
        }

        #endregion
        /// <summary>
        /// 构造函数
        /// </summary>
        public EntityBaseControl ()
        {
            this.IsEntityUseCache = true;
            this.IsEncryptKey = true;
        }


        protected abstract void InitKey();


        /// <summary>
        /// 从数据库设置数据到控件
        /// </summary>
        public void SetControlValueFromDb()
        {
            if (!IsUseKey || !this.IsAdd)
            {
                this.GetEntityFromDb();
                this.EntityToControl();
            }
        }

        public const string ShowDialog_TypeInfo = "info";
        public const string ShowDialog_TypeUpdate = "update";
        public const string ShowDialog_TypeAdd = "add";
        public static Page page;
        /// <summary>
        /// 提示信息,type=类型,msg=消息内容
        /// </summary>
        public Action<string,string> ShowDialog = (type,msg) =>
        {
            if (page != null)
            {
                ARS.Control.Interface.IDialog dialog = ARS.Control.Factory.DialogFactory.CreateDialog();
                if (type == ShowDialog_TypeInfo)
                {
                    
                    //string msg = string.Format("不能为空:{0}!", form.Field.Verbose_Name);
                    string str1 =
                        ARS.PublicTool.WebHelper.WebPage.ScriptHelper.GetScriptStr(dialog.ShowInfo(page,
                            typeof(EntityControl), msg));
                    page.ClientScript.RegisterStartupScript(typeof(EntityControl), "on", str1);
                }
                else if (type == ShowDialog_TypeUpdate)
                {
                    page.ClientScript.RegisterStartupScript(typeof(EntityControl), "ad",
                                            ARS.PublicTool.WebHelper.WebPage.ScriptHelper.GetScriptStr(
                                                dialog.ShowUpdateInfo(page,
                                                    typeof(EntityControl), Int32.Parse(msg), true)));                    
                }
                else if (type == ShowDialog_TypeAdd)
                {
                    page.ClientScript.RegisterStartupScript(typeof(EntityControl), "ad",
                        ARS.PublicTool.WebHelper.WebPage.ScriptHelper.GetScriptStr(
                            dialog.ShowAddInfo(page,
                                typeof(EntityControl), Int32.Parse(msg), true)));  
                }
            }
        }; 

        #region 读取数据
        private DataSet dateSet = null;
        /// <summary>
        /// 从数据库获取实体的数据源
        /// </summary>
        /// <returns></returns>
        public virtual DataSet GetEntityDsFromDb()
        {
            if (this.dateSet == null)
            {
                if (this.IsUseKey)
                {
                    this.dateSet = DbProvider.Query(EntityToSql.GetSelectSql());
                }
                else
                {

                    if (this.dateSet == null)
                    {
                        this.dateSet = this.DbProvider.Query(this.EntityToSql.GetSelectSql(QueryWhere));
                        int count = dateSet.Tables[0].Rows.Count;
                        if (count == 1)
                        {
                            this.IsAdd = false;
                        }
                        else if (count > 0)
                        {
                            HttpContext.Current.Response.Write("查询结果有" + count.ToString() + "项，无法锁定编辑项，终止编辑!");
                            HttpContext.Current.Response.End();
                        }
                        else
                        {
                            this.IsAdd = true;
                        }
                    }
                    return dateSet;
                }
            }
            return this.dateSet;
        }

        /// <summary>
        /// 从数据库获取model
        /// </summary>
        private void GetEntityFromDb()
        {
            DataSet ds = this.GetEntityDsFromDb();
            if (ds != null)
            {
                DataTable dt = ds.Tables[0];
                if (dt.Rows.Count > 0)
                {
                    //controls = EntityTableInfo.GetControls(this.IsAdd);
                    foreach (Field field in EntityTableInfo.FieldList)
                    {
                        //var item = control;
                        if (dt.Columns.Contains(field.Db_Field_Name))
                        {

                            field.Value = dt.Rows[0][field.Db_Field_Name];
                        }
                        else
                        {
                            field.Widget.SetInputValue(this.EntityTableInfo.KeyInfo);
                        }
                    }
                }
            }
        }
        #endregion

        #region 检测数据

        public bool CheckData(List<Fields.Field> list)
        {
            string where;
            foreach (var field in list)
            {
                if (!field.IsAllowBlank)
                {
                    if (field.Value == null)
                    {
                        string msg = string.Format("不能为空:{0}!", field.Verbose_Name);
                        this.ShowDialog(ShowDialog_TypeInfo, msg);
                        return false;
                    }
                }
                if (field.IsUnique)
                {

                    if (UniqueWhereEvent != null)
                    {
                        where = this.UniqueWhereEvent(field);
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(field.UniqueWhere))
                        {
                            where = "1=1";
                        }
                        else
                        {
                            where = field.UniqueWhere;
                        }
                    }
                    string sql;
                    if (this.IsAdd)
                    {
                        sql = "select 1 from {0} where {1} and {2}='{3}'";
                    }
                    else
                    {
                        sql = "select 1 from {0} where {1} and {2}='{3}' and " + EntityTableInfo.KeyInfo.Key + "!=" + EntityTableInfo.KeyInfo.Value;

                    }
                    sql = string.Format(sql, EntityTableInfo.TableName, where, field.Db_Field_Name, field.Value);
                    if (DbProvider.Exists(sql))
                    {
                        string msg = string.Format("已存在:{0}!", field.Verbose_Name);
                        this.ShowDialog(ShowDialog_TypeInfo, msg);

                        return false;
                        break;
                    }
                }
                if (field.MinLength > 0)
                {
                    if (field.Value == null || field.Value.ToString().Length<field.MinLength)
                    {
                        string msg = string.Format("不能少于{1}位:{0}!", field.Verbose_Name, field.MinLength);
                        this.ShowDialog(ShowDialog_TypeInfo, msg);
                        return false;
                    }
                }
                if (field.MaxLength > 0)
                {
                    if (field.Value == null || field.Value.ToString().Length > field.MaxLength)
                    {
                        string msg = string.Format("不能超过{1}位:{0}!", field.Verbose_Name, field.MaxLength);
                        this.ShowDialog(ShowDialog_TypeInfo, msg);
                        return false;
                    }
                }
                else
                {

                }
            }
            return true;
        }

        /// <summary>
        /// 检测重复数据，非空数据等
        /// </summary>
        /// <param name="dialog"></param>
        /// <returns></returns>
        public bool CheckData()
        {
            return CheckData(EntityTableInfo.FieldList);
        }
        #endregion


        /// <summary>
        /// 委托
        /// </summary>
        /// <param name="control"></param>
        /// <returns>返回false则不执行操作</returns>
        public delegate string AddEntityToDbDelegate(ARS.Control.Custom.Entity.Fields.Field field);
        /// <summary>
        /// 添加前回调
        /// </summary>
        public event AddEntityToDbDelegate AddEntityToDbEvent;
        /// <summary>
        /// 修改前回调
        /// </summary>
        public event AddEntityToDbDelegate UpdateEntityToDbEvent;


        public delegate void EntityToDbAfterDelegate(List<ARS.Control.Custom.Entity.Fields.Field> list, int newId);
        /// <summary>
        /// 完成后回调
        /// </summary>
        public event EntityToDbAfterDelegate EntityToDbAfterEvent = delegate { };

        public delegate string InitCheckDelegate(List<ARS.Control.Custom.Entity.Fields.Field> list);
        /// <summary>
        /// 加载前回调
        /// </summary>
        public event InitCheckDelegate InitCheckEvent;


        public delegate string UniqueWhereDelegate(ARS.Control.Custom.Entity.Fields.Field field);
        public event UniqueWhereDelegate UniqueWhereEvent;



        #region 保存到数据库

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="list"></param>
        /// <param name="getSqlParams"></param>
        /// <param name="fun"></param>
        /// <returns></returns>
        private int ModifyEntity(List<ARS.Control.Custom.Entity.Fields.Field> list,
            Func<List<ARS.Control.Custom.Entity.Fields.Field>, string> getSqlParams, AddEntityToDbDelegate fun)
        {
            //调用委托


            foreach (var control in list)
            {
                //隐藏空间
                if (control is HiddenInputField)
                {
                    HiddenInputField hiddenInputField = (HiddenInputField) control;
                    hiddenInputField.InitInputValue(this);
                }
                else
                {
                    control.Value = control.Widget.GetInputValue();
                }
                if (fun != null)
                {
                    string msg = fun(control);
                    if (msg == null)
                    {

                    }
                    else
                    {
                        this.ShowDialog(ShowDialog_TypeInfo, msg);
                        return 0;
                    }
                }

            }
            List<ARS.Control.Custom.Entity.Fields.Field> listNow;
            if (this.IsAdd)
            {
                listNow = EntityTableInfo.GetFields(EntityModel.TYPE_ADD);
            }
            else
            {
                listNow = EntityTableInfo.GetFields(EntityModel.TYPE_MODIFY);
            }
            if (this.IsAdd)
            {
                listNow = listNow.Where(form => form.IsSaveDb && form.Value != null).ToList();

            }
            else
            {
                listNow = listNow.Where(field => field.IsSaveDb && (!(field is FloatField) || (field.Value != null && field.Value.ToString() != ""))).ToList();
//                listNow =
//                    listNow.Skip(field => field is FloatField&&(field.Value==null || field.Value.ToString()=="")).Take(form => form.IsSaveDb)
//                        .ToList();
            }

            if (CheckData(listNow))
            {
                string sql = getSqlParams(listNow);
                var b = EntityTableInfo.GetParameters(listNow);
                if (string.IsNullOrEmpty(sql) || b == null)
                {
                    return 0;
                }
                object obj = DbProvider.GetSingle(sql, b);
                int newId = Convert.ToInt32(obj);
                if (this.IsAdd)
                {
                    this.ShowDialog(ShowDialog_TypeAdd, newId.ToString());
//                    this.Page.ClientScript.RegisterStartupScript(typeof(EntityControl), "ad",
//                        ARS.PublicTool.WebHelper.WebPage.ScriptHelper.GetScriptStr(
//                            this.GetDialog().ShowAddInfo(this.Page, typeof(EntityControl), newId
//                                , true)));
                }
                else
                {
                    this.ShowDialog(ShowDialog_TypeUpdate, newId.ToString());
//                    this.Page.ClientScript.RegisterStartupScript(typeof(EntityControl), "ad",
//                        ARS.PublicTool.WebHelper.WebPage.ScriptHelper.GetScriptStr(
//                            this.GetDialog().ShowUpdateInfo(this.Page,
//                                typeof(EntityControl), EntityTableInfo.KeyInfo.Value, true)));
                }

                EntityToDbAfterEvent(list, newId);
                return newId;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 添加实体到数据库
        /// </summary>
        /// <returns></returns>
        public int AddEntityToDb()
        {
            return ModifyEntity(EntityTableInfo.FieldList, EntityToSql.GetAddSqlParams, this.AddEntityToDbEvent);
        }


        /// <summary>
        /// 查询条件List
        /// </summary>
        public List<WhereField> WhereFieldList
        {
            get;
            set;
        }

        private string _queryWhere;
        /// <summary>
        /// 查询条件:string
        /// </summary>
        public string QueryWhere
        {
            get
            {
                if (_queryWhere == null)
                {
                    if (WhereFieldList != null)
                    {
                        _queryWhere = string.Join(" and ", WhereFieldList.Select(item => { return string.Format("{0}='{1}'", item.FieldName, item.Value); }).ToArray());
                    }
                }
                return _queryWhere;
            }
            set
            {
                this._queryWhere = value;
            }
        }

        public virtual string GetUpdateWhere()
        {
            if (IsUseKey)
            {
                return null;
            }
            else
            {
                return QueryWhere;
            }

        }

        public string GetUpdateSqlParams(List<ARS.Control.Custom.Entity.Fields.Field> controls)
        {
            return EntityToSql.GetUpdateSqlParams(controls, this.GetUpdateWhere());
        }

        /// <summary>
        /// 更新实体到数据库
        /// </summary>
        /// <returns></returns>
        public bool UpdateEntityToDb()
        {
            if (ModifyEntity(EntityTableInfo.FieldList, this.GetUpdateSqlParams, this.UpdateEntityToDbEvent) > 0)
            {

                return true;
            }
            else
            {
                return false;
            }
        }
        public virtual int AddOrUpdateEntityToDb()
        {
            if (this.IsAdd)
            {
                return this.AddEntityToDb();
            }
            else
            {
                return this.UpdateEntityToDb() ? 1 : 0;
            }
        }

        #endregion


        /// <summary>
        /// 是否加载
        /// </summary>
        //private bool _IsInit = false;

        private void Init()
        {
            if (this.Page!=null && this.Page.IsPostBack)
            {
                this.ControlToEntity();
            }
            else
            {
                this.SetControlValueFromDb();
            }
        }


        public void InitFromJs()
        {
            this.OnLoad(null);
        }

        //override on
        protected override void OnLoad(EventArgs e)
        {
            if (this.Visible)
            {
                page = this.Page;
                if (!this.IsUseKey)
                {
                    this.GetEntityDsFromDb();
                }
                this.InitKey();
                this.Init();
                if (this.InitCheckEvent != null)
                {
                    string str = InitCheckEvent(EntityTableInfo.FieldList);
                    if (!string.IsNullOrEmpty(str))
                    {
                        this.ShowDialog(ShowDialog_TypeInfo, str);
                        this.Visible = false;

                        return;
                    }
                }
                base.OnLoad(e);
            }

        }


        #region

        /// <summary>
        /// 实体到数据库
        /// </summary>
        public abstract void EntityToControl();
        /// <summary>
        /// 控件到实体
        /// </summary>
        public abstract void ControlToEntity();

        ///// <summary>
        ///// 错误信息提示
        ///// </summary>
        //public abstract void ShowErrorInfo(string msg);

        //public abstract void ShowAddInfo(string msg);

        //public abstract void ShowUpdateInfo(string msg);

        /// <summary>
        /// 获取对话框
        /// </summary>
        /// <returns></returns>
        protected abstract ARS.Control.Interface.IDialog GetDialog();
        #endregion
    }
}
